home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 18 / CU Amiga Magazine's Super CD-ROM 18 (1997)(EMAP Images)(GB)[!][issue 1998-01].iso / CUCD / Online / CNetDemo / cnet / sdk / empty.c
Encoding:
C/C++ Source or Header  |  1997-09-04  |  28.2 KB  |  789 lines

  1. /************************************************************************
  2.  *    CNet/3 and CNet/4  C language interface routines and examples     *
  3.  *                                                                      *
  4.  *  copyright © 1996 ZenMetal Software ... this code may be freely      *
  5.  *  distributed to and used by registered CNet owners EXCLUSIVELY.      *
  6.  *  Other distribution is in violation of copyright laws.               *
  7.  ************************************************************************/
  8.  
  9.  
  10.  
  11. /************************************************************************
  12.  *                          Function prototypes                         *
  13.  ************************************************************************/
  14. void        CallHost( UBYTE c );
  15. void        ShutDown( char *spawn );
  16. void        GetOut( void );
  17. int        intGetOut( void );
  18. void        LoadError( void );
  19.  
  20.  
  21. /************************************************************************
  22.  *                           Global Variables                           *
  23.  ************************************************************************/
  24. struct MsgPort         *replyp;    /* Some communication details ...    */
  25. struct CPort           *cport;
  26. struct CMessage        cmess;
  27. struct MainPort        *myp;        /* Pointer to CNet port--ALL info!    */
  28. struct PortData        *z;
  29. char                     **bm;
  30. struct Library         *CNetBase = NULL;
  31. struct SignalSemaphore *SEM;
  32.  
  33.  
  34.  
  35. /************************************************************************
  36.  *                             Main routine                             *
  37.  ************************************************************************/
  38. void main( int argc, char **argv )
  39. {
  40.     Forbid();
  41.     if(argc > 1) cport = (struct CPort *)FindPort( argv[1] );
  42.     Permit();
  43.  
  44.     if( argc<2 || !(cport) ) {
  45.         printf("This is a CNet C program.\n");
  46.         exit(0);
  47.         }
  48.  
  49.     if( !(replyp = CreatePort( 0,0 )))
  50.         exit(0);
  51.  
  52.     cmess.cn_Message.mn_ReplyPort   = replyp;
  53.     cmess.cn_Message.mn_Length      = sizeof( struct CMessage );
  54.     cmess.cn_Message.mn_Node.ln_Name= "cstuff";
  55.  
  56.     // CNet version check
  57.     if( cport->ack != 30 ) {
  58.         cport->ack = 1;
  59.         LoadError();
  60.         }
  61.  
  62.     cport->ack = 0;
  63.  
  64.     z    = cport->zp;
  65.     myp  = cport->myp;
  66.     SEM  = myp->SEM;
  67.     bm   = z->bm;
  68.  
  69.     if( !(CNetBase = OpenLibrary( "cnet.library", 4 )) ) // <- NOTE version 4 - can be changed to 3 to make compatible with older CNet releases!
  70.         LoadError();
  71.  
  72.     atexit(GetOut); // inserts an exit trap.  When exit() is called, the
  73.                    // code in GetOut() is invoked.
  74.  
  75.     onbreak(intGetOut); // this break trap causes the program to exit when
  76.                   // the program receives a break (CTRL-C) signal
  77.  
  78. /************************************************************************
  79.  *           End of CNet setup - YOUR CUSTOM CODE STARTS HERE           *
  80.  ************************************************************************/
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.     /************************************************************************
  88.      *                         exit back to CNet!
  89.      ************************************************************************/
  90.     // Be sure to insert (or call) your cleanup code in the GetOut() function
  91.    // below
  92.  
  93.     exit(0);
  94. }
  95.  
  96.  
  97. /**************************************************************************
  98.  *       Routine called if Load error (wrong CNet version, etc,...        *
  99.  **************************************************************************/
  100. void LoadError( void )
  101. {
  102.     if(replyp)
  103.         {
  104.         // Use while(GetMsg(replyp) here to get any pending msgs before deleting port!
  105.         DeletePort( replyp );
  106.         }
  107.     exit(0);
  108. }
  109.  
  110.  
  111.  
  112. /**************************************************************************
  113.  *       An added function to call GetOut() for onbreak() support         *
  114.  **************************************************************************/
  115. int intGetOut( void )
  116. {
  117.     exit(0);
  118.     return 0;
  119. }
  120.  
  121.  
  122. /************************************************************************
  123.  *                           Generic EXIT code                          *
  124.  ************************************************************************/
  125. void GetOut( void )
  126. {
  127.     struct Message *dmsg;
  128.  
  129.     // PUT YOUR CLEANUP CODE HERE!
  130.     // Anything that needs to be cleaned up when CTRL-C is sent to your
  131.     // program, if "BREAK <tasknum>" is used in a shell to break your program
  132.     // or cleanup required when exit() is called needs to be done here!
  133.  
  134.     ShutDown( NULL );
  135.     if(replyp)
  136.         DeletePort( replyp );
  137. }
  138.  
  139.  
  140. /**************************************************************************
  141.  *                         another file to run?                           *
  142.  **************************************************************************/
  143. void ShutDown( char *spawn )
  144. {
  145.     /* spawn = full path/file to run */
  146.     if( spawn )
  147.         strcpy( z->CSpawn, spawn );
  148.  
  149.     CallHost( 0 );
  150. }
  151.  
  152.  
  153. void CallHost( UBYTE c )
  154. {
  155.     cmess.command = c;
  156.     PutMsg  ( (struct MsgPort *)cport, (struct Message *)&cmess );
  157.     WaitPort( replyp );
  158.     GetMsg  ( replyp );
  159. }
  160.  
  161. void PutText( char *text )
  162. {
  163.     cmess.arg1 = (ULONG)text;    /* text to print        */
  164.     CallHost( 1 );
  165. }
  166.  
  167. void PutA( void )
  168. {
  169.     PutText( z->ABuffer );
  170. }
  171.  
  172.  
  173. /**************************************************************************
  174.  *    ENTERLINE FLAGS:                                                    *
  175.  *    Construct by ORing the following bit defines:                       *
  176.  *                                                                        *
  177.  * ie. EnterLine(3, ELINE_ALLCAPS|ELINE_INPOUTBOX, "My Prompt>");         *
  178.  *                                                                        *
  179.  *     FLAGS:                                                             *
  180.  *     ------                                                             *
  181.  *     ELINE_ALLCAPS       = All capitalized                              *
  182.  *     ELINE_FILENAME      = FILENAME.  Don't allow =":; or asterisk      *
  183.  *     ELINE_USEINBUFF     = Begin with existing z.InBuffer               *
  184.  *     ELINE_NOLEADSPACE   = Chop leading spaces                          *
  185.  *     ELINE_CAPWORDSTART  = Force 1st letter of word caps                *
  186.  *     ELINE_RESTWORDLOWER = Force all others lower case                  *
  187.  *     ELINE_NUMBERSONLY   = Numeric input only                           *
  188.  *     ELINE_INPUTBOX      = Print input box (terminated with . )         *
  189.  *     ELINE_ALLOWMCI      = DO allow MCI                                 *
  190.  *     ELINE_HANDLESPECIAL = HANDLES/SPECIAL.  Don't allow ^_`{|}~@       *
  191.  *     ELINE_XSLASHSTART   = Exit for . or / at beginning of line         *
  192.  *     ELINE_XBKSPACESTART = Exit for backspace at beginning of line      *
  193.  *     ELINE_NOOLMS        = Do not allow OLM's to appear while editing   *
  194.  *     ELINE_ALLOWCHAT     = Allow Chat break in at this prompt. COMMAND  *
  195.  *                           PROMPT.                                      *
  196.  *     ELINE_NOSPACES      = Don't allow SPACES                           *
  197.  *     ELINE_NOCURSORMOVE  = DON'T ALLOW MOVEMENT                         *
  198.  *     ELINE_NOSLASHES     = Don't allow forward slash                    *
  199.  *                                                                        *
  200.  *  NOTE: The old "numeric" flag values still work 100% ..                *
  201.  **************************************************************************/
  202. int EnterLine( UBYTE len, ULONG flags, char *prompt )
  203. {
  204.     cmess.arg1 = (ULONG)len;     /* how many chars max to input    */
  205.     cmess.arg2 = (ULONG)flags;   /* flags describing required input handling */
  206.     cmess.arg3 = (ULONG)prompt;  /* text to print before input    */
  207.     CallHost( 2 );               /* result is in z->InBuffer    */
  208.  
  209.     return( (int)strlen( z->InBuffer ));
  210. }
  211.  
  212.  
  213. /**************************************************************************
  214.  *                       Stop until a key is pressed                      *
  215.  **************************************************************************/
  216. char OneKey( void )
  217. {
  218.     CallHost( 3 );
  219.     return( (char)cmess.result );    /* function returns ASCII value of key pressed */
  220. }
  221.  
  222.  
  223. /**************************************************************************
  224.  *
  225.  **************************************************************************/
  226. void EnterPassword( UBYTE len )
  227. {
  228.     cmess.arg1 = (ULONG)len;    /* max number of characters */
  229.     CallHost( 4 );
  230. }
  231.  
  232. /**************************************************************************
  233.  *                 Check z->InBuffer for Chat, OLM, etc                   *
  234.  **************************************************************************/
  235. long CommonCommands( void )
  236. {
  237.     CallHost( 5 );
  238.     return( (long)cmess.result );
  239. }
  240.  
  241.  
  242. /**************************************************************************
  243.  *
  244.  **************************************************************************/
  245. UBYTE ReadFile( char *path, UBYTE flags )
  246. {
  247.     cmess.arg1 = (ULONG)path;
  248.     cmess.arg2 = (ULONG)flags;          /* 1 = print File Not Found */
  249.     CallHost( 6 );
  250.     return( (UBYTE)cmess.result );      /* returns FALSE if File Not Found */
  251. }
  252.  
  253. /**************************************************************************
  254.  *        Sets the "Action" or "Where" field for the user's port          *
  255.  *      ** remember to retain and restore the previous z->DOING **        *
  256.  **************************************************************************/
  257. void SetDoing( char *what )
  258. {
  259.     cmess.arg1 = (ULONG)what;
  260.     CallHost( 7 );
  261. }
  262.  
  263.  
  264. /**************************************************************************
  265.  *Invokes the CNet editor according to user's preference of line or Visual*
  266.  **************************************************************************/
  267. void CallEditor( short max, short inlines )
  268. {
  269.     cmess.arg1 = (ULONG)max;    /* Maximum number of lines (250)*/
  270.     cmess.arg2 = (ULONG)inlines;    /* TRUE/FALSE use existing _edbuff? */
  271.     CallHost( 8 );
  272. }
  273.  
  274. /**************************************************************************
  275.  *             Read text file with MCI/graphic interpretation             *
  276.  **************************************************************************/
  277. UBYTE ReadGraphics( char *path, char flags )
  278. {
  279.     cmess.arg1 = (ULONG)path;
  280.     cmess.arg2 = (ULONG)flags;    /* 1 = print File Not Found    */
  281.     CallHost( 9 );
  282.     return( (UBYTE)cmess.result );        /* FALSE if File Not Found    */
  283. }
  284.  
  285. /**************************************************************************
  286.  *  Construct a date in CNet format - like that seen in the port titlebar *
  287.  **************************************************************************/
  288. void MakeDate( struct IsDate *date, char *output )
  289. {
  290.     cmess.arg1 = (ULONG)date;
  291.     cmess.arg2 = (ULONG)output;
  292.     CallHost( 10 );
  293. }
  294.  
  295.  
  296. /**************************************************************************
  297.  *                     Load userdata for account "id"                     *
  298.  **************************************************************************/
  299. UBYTE ReadAccount( short id, struct UserData *user )
  300. {
  301.     cmess.arg1 = (ULONG)id;
  302.     cmess.arg2 = (ULONG)user;
  303.     CallHost( 11 );
  304.     return( (UBYTE)cmess.result );
  305. }
  306.  
  307. /**************************************************************************
  308.  *           Saves an account after editing/changing attributes           *
  309.  **************************************************************************/
  310. UBYTE SaveAccount( struct UserData *user, short id )
  311. {
  312.     cmess.arg1 = (ULONG)user;
  313.     cmess.arg2 = (ULONG)id;
  314.     CallHost( 12 );
  315.     return( (UBYTE)cmess.result );
  316. }
  317.  
  318. /**************************************************************************
  319.  *         add charge amount "a" to charge schedule number "n"            *
  320.  **************************************************************************/
  321. UBYTE AddCharge( short n, short a )
  322. {
  323.     cmess.arg1 = (ULONG)n;
  324.     cmess.arg2 = (ULONG)a;
  325.     CallHost( 13 );
  326.     return( (UBYTE)cmess.result );
  327. }
  328.  
  329. /**************************************************************************
  330.  *
  331.  **************************************************************************/
  332. UBYTE CheckBalance( short n, short a )
  333. {
  334.     cmess.arg1 = (ULONG)n;
  335.     cmess.arg2 = (ULONG)a;
  336.     CallHost( 14 );
  337.     return( (UBYTE)cmess.result );
  338. }
  339.  
  340. /***************************************************************************
  341.  * Get text from user.  Results are placed in z.GBuffer[] array of strings *
  342.  * note that there are 16 lines MAX and each line may hold up to 80        *
  343.  * characters                                                              *
  344.  ***************************************************************************/
  345. int EnterText( char firstchar, short maxchars, short perline, short maxlines )
  346. {
  347.     cmess.arg1 = (ULONG)firstchar;
  348.     cmess.arg2 = (ULONG)maxchars;
  349.     cmess.arg3 = (ULONG)perline;
  350.     cmess.arg4 = (ULONG)maxlines;
  351.     CallHost( 15 );
  352.     return( (int)cmess.result );
  353. }
  354.  
  355. /**************************************************************************
  356.  *
  357.  **************************************************************************/
  358. long ConferenceWait( short a )
  359. {
  360.     cmess.arg1 = (ULONG) a;
  361.     CallHost( 16 );
  362.     return( (long)cmess.result );
  363. }
  364.  
  365.  
  366. /****************************************************************************
  367.  * Update the current time, load the user's bbstext translation, charges    *
  368.  * If the user has little time remaining, print "you have xx minutes left", *
  369.  * force Events to be checked for pending event execution..                 *
  370.  ****************************************************************************/
  371. void CheckChanges( void )
  372. {
  373.     CallHost( 17 );
  374. }
  375.  
  376.  
  377. /**************************************************************************
  378.  *      Converts a CNet access/range string to a packed LONG value        *
  379.  **************************************************************************/
  380. long ConvertAccess( char *s )
  381. {
  382.     cmess.arg1 = (ULONG)s;
  383.     CallHost( 18 );
  384.     return( (long)cmess.result );
  385. }
  386.  
  387.  
  388. /**************************************************************************
  389.  * return the number of bytes free on device specified by s               *
  390.  * if q==0, the result is displayed to the user by GetFree()              *
  391.  **************************************************************************/
  392. long GetFree( char *s, UBYTE q )
  393. {
  394.     cmess.arg1 = (ULONG)s;
  395.     cmess.arg2 = (ULONG)q;
  396.     CallHost( 19 );
  397.     return( (long)cmess.result );
  398. }
  399.  
  400. /**************************************************************************
  401.  *    Find an account based on account number, Handle or real name        *
  402.  *    This is the same routine that, if the user is not found, pops up    *
  403.  *    the mini-userlist for user choice.                                  *
  404.  **************************************************************************/
  405. short FindAccount( char *a, struct UserData *b, UBYTE quiet )
  406. {
  407.     /* a     = handle, name, account number to find
  408.     * b     = pointer to instance of struct UserData, where loaded account will
  409.     *         be placed.
  410.     * quiet = if account not found, do not print "could not find 'a'".
  411.     *
  412.     * also, you can set z.DoQuick=1 BEFORE calling FindAccount() if you do
  413.     * NOT want CNet to pop up the mini-handle/userlist.
  414.     */
  415.     
  416.     cmess.arg1 = (ULONG)a;
  417.     cmess.arg2 = (ULONG)b;
  418.     cmess.arg3 = (ULONG)quiet;
  419.     CallHost( 20 );
  420.     return( (short)cmess.result );
  421. }
  422.  
  423.  
  424. /**************************************************************************
  425.  *  Forces CNet to flush/check it's buffers and parse/update the keyboard *
  426.  *  buffers                                                               *
  427.  **************************************************************************/
  428. void CheckFlowControl( void )
  429. {
  430.     CallHost( 21 );
  431. }
  432.  
  433. /**************************************************************************
  434.  * list the contents of a directory (the user will be prompted for        *
  435.  * directory name).                                                       *
  436.  *                                                                        *
  437.  * options: a = allow selection of files to user's select list            *
  438.  *                                                                        *
  439.  *          b = 1: select and download immediately                        *
  440.  *              2: allow wildcard pattern                                 *
  441.  *                                                                        *
  442.  *          c = list files newer than the date specified by c             *
  443.  *              c is a properly filled out Cnet IsDate structure          *
  444.  **************************************************************************/
  445. long ListDir( UBYTE a, UBYTE b, struct IsDate *c )
  446. {
  447.     cmess.arg1 = (ULONG)a;
  448.     cmess.arg2 = (ULONG)b;
  449.     cmess.arg3 = (ULONG)c;
  450.     CallHost( 22 );
  451.     return( (long)cmess.result );
  452. }
  453.  
  454.  
  455. /**************************************************************************
  456.  * Read the next base/udbase message                                      *
  457.  **************************************************************************/
  458. UBYTE Rnext( void )
  459. {
  460.     CallHost( 24 );
  461.     return( (UBYTE)cmess.result );
  462. }
  463.  
  464. /***************************************************************************
  465.  * Parse the contents of z->InBuffer into z->pitems.  Parses up to numargs *
  466.  * items                                                                   *
  467.  ***************************************************************************/
  468. void ParseCommandLine( UBYTE numargs )
  469. {
  470.     cmess.arg1 = (ULONG)numargs;
  471.     CallHost( 25 );
  472. }
  473.  
  474.  
  475. /**************************************************************************
  476.  *  Takes the contents of z->InBuffer and searches for a matching command *
  477.  *  in menu "num" of BBSMENU.                                             *
  478.  **************************************************************************/
  479. short FindCommand( short num )
  480. {
  481.     cmess.arg1 = (ULONG) num;
  482.     CallHost( 26 );
  483.     return( (short)cmess.result );
  484. }
  485.  
  486. /**************************************************************************
  487.  * Open the filename specified by a, seek to position b in the file       *
  488.  * and display the contents of the file from point b to EOF               *
  489.  **************************************************************************/
  490. void ReadMessagePoint( char *a, long b )
  491. {
  492.     cmess.arg1 = (ULONG) a;
  493.     cmess.arg2 = (ULONG) b;
  494.     CallHost( 27 );
  495. }
  496.  
  497. /**************************************************************************
  498.  * Use the CNet editor to edit the file specified by "file"               *
  499.  **************************************************************************/
  500. void EditMessage( char *file )
  501. {
  502.     cmess.arg1 = (ULONG) file;
  503.     CallHost( 28 );
  504. }
  505.  
  506. /***************************************************************************
  507.  * Load the text from the file-handle given and insert it into the current *
  508.  * port's editor file                                                      *
  509.  ***************************************************************************/
  510. void LoadText( BPTR fh )
  511. {
  512.     cmess.arg1 = (ULONG) fh;
  513.     CallHost( 29 );
  514. }
  515.  
  516.  
  517. /**************************************************************************
  518.  *    1000000 mics = 1 second                                                *
  519.  **************************************************************************/
  520. char WaitForInput( long mics )
  521. {
  522.     cmess.arg1 = (ULONG) mics;
  523.     CallHost( 31 );
  524.     return( (char)cmess.result );
  525. }
  526.  
  527.  
  528. /**************************************************************************
  529.  *                       Select and download a file.                      *
  530.  *                                                                        *
  531.  * file  = full path/filename                                             *
  532.  *                                                                        *
  533.  * flags = 0 -> select without immediate download                         *
  534.  *       = 1 -> select and download immediately                           *
  535.  *                                                                        *
  536.  * flag values below are new for v4.11                                    *
  537.  *                                                                        *
  538.  *       = 2 -> delete file after downloading/no immediate download       *
  539.  *       = 3 -> delete file after downloading/download immediate.         *
  540.  **************************************************************************/
  541. UBYTE SelectAndDownload( char *file, UBYTE flags )
  542. {
  543.     cmess.arg1 = (ULONG)file;
  544.     cmess.arg2 = (ULONG)flags;
  545.     CallHost( 39 );
  546.     return( (UBYTE)cmess.result );
  547. }
  548.  
  549.  
  550. /**************************************************************************
  551.  * file: the ".vde" filename, without the ".vde"!                         *
  552.  * data: pointer to the structure you are going to edit                   *
  553.  * size: structure length in bytes                                        *
  554.  *                                                                        *
  555.  * returns: TRUE  if structure has been changed                           *
  556.  *          FALSE otherwise                                               *
  557.  **************************************************************************/
  558. short VisualDataEditor( char *file, void *data, long size )
  559. {
  560.     cmess.arg1 = (ULONG)file;
  561.     cmess.arg2 = (ULONG)data;
  562.     cmess.arg3 = (ULONG)size;
  563.     CallHost( 40 );
  564.     return( (short)cmess.result );
  565. }
  566.  
  567. /**************************************************************************
  568.  * In preparation for an ExtUpload, this function                         *
  569.  * sets the minimum number of free bytes to maintain on the    drive.        *
  570.  **************************************************************************/
  571. void ExtSetMinFree( long free )
  572. {
  573.     cmess.arg1 = (ULONG)free;
  574.     CallHost( 42 );
  575. }
  576.  
  577.  
  578. /**************************************************************************
  579.  * In preparation for an ExtDownload or an ExtUpload, this function       *
  580.  * sets the protocol to be used.  If you send NULL, it will allow the     *
  581.  * user to choose his OWN protocol.                                       *
  582.  *                                                                        *
  583.  * Otherwise, you may select 'a' to be the first letter of a valid        *
  584.  * system protocol (from BBSPROTO file), such as 'x', 'z', etc.           *
  585.  *                                                                        *
  586.  * TRUE will be returned if a protocol is selected and ready, FALSE       *
  587.  * if there is a problem.                                                 *
  588.  **************************************************************************/
  589. UBYTE ExtSetProtocol( char a )
  590. {
  591.     cmess.arg1 = (ULONG)a;
  592.     CallHost( 43 );
  593.     return( (UBYTE)cmess.result );
  594. }
  595.  
  596.  
  597.  
  598. /**************************************************************************
  599.  * This routine allows the user to download the SINGLE file specified     *
  600.  * by the FULL PATH 'args'.                                               *
  601.  *                                                                        *
  602.  *    Currently, NULL is always returned.                                    *
  603.  **************************************************************************/
  604. char *ExtDownload( char *args )
  605. {
  606.     cmess.arg1 = (ULONG)args;
  607.     CallHost( 44 );
  608.     return( (char *)cmess.result );
  609. }
  610.  
  611.  
  612. /**************************************************************************
  613.  * This routine allows the user to upload the file specified by           *
  614.  * 'args'.  The path for uploading will be taken from the path            *
  615.  * in 'args'.  If you do NOT specify a path, the file(s) will             *
  616.  * appear in the user's HOME directory.                                   *
  617.  *                                                                        *
  618.  * Note that with batch protocols like ZMODEM, the filename(s) are        *
  619.  * taken from the header packet information, and may NOT be the           *
  620.  * same as what you have requested the user upload.  For this reason,     *
  621.  * you should have uploads occur in a TEMP directory, and search that     *
  622.  * directory yourself for new files.                                      *
  623.  *                                                                        *
  624.  * Currently, NULL is always returned.                                    *
  625.  **************************************************************************/
  626. char *ExtUpload( char *args )
  627. {
  628.     cmess.arg1 = (ULONG)args;
  629.     CallHost( 45 );
  630.     return( (char *)cmess.result );
  631. }
  632.  
  633. /**************************************************************************
  634.  * Write myp->Key[] to bbs.ukeys in a CNet friendly manner
  635.  * getsem: 0 = do not lock the key semaphore
  636.  *         1 = lock the key semaphore before writing
  637.  *
  638.  * the key semaphore is myp->SEM[1] so, if you have already performed
  639.  * ObtainSemaphore(myp->SEM[1]), then use WriteBBSKeys(0)
  640.  * if you have not locked the semaphore, use WriteBBSKeys(1)
  641.  *
  642.  * notes:
  643.  *
  644.  * if a user's account data is altered, you must also copy the
  645.  * handle, MailID (AKA UUCP ID), Real Name, etc, to myp->Key[AccountNumber]
  646.  *
  647.  * Please see the structure definition for KeyElement4 in users.h to
  648.  * see what data is saved to myp->Key[x]
  649.  *
  650.  * After doing this, the key array must be written to bbs.ukeys.  This
  651.  * function facilitates all the grunt work of writing the key array
  652.  * in the proper size.
  653.  *
  654.  **************************************************************************/
  655. BYTE WriteUKeys( BYTE getsem )
  656. {
  657.     CallHost( 58 );
  658.     return( (BYTE)cmess.result );
  659. }
  660.  
  661. void DoANSI( UBYTE n, USHORT a, USHORT b)
  662. {
  663.     cmess.arg1 = (ULONG)n;
  664.     cmess.arg2 = (ULONG)a;
  665.     cmess.arg3 = (ULONG)b;
  666.     CallHost( 59 );
  667.     return;
  668. }
  669.  
  670. void DoANSIOut( UBYTE n)
  671. {
  672.     cmess.arg1 = (ULONG)n;
  673.     CallHost( 60 );
  674.     return;
  675. }
  676.  
  677.  
  678. /**************************************************************************
  679.  * compare two strings and return result                                  *
  680.  *                                                                        *
  681.  * result: 0 if equal                                                     *
  682.  *        >0 if s is alphabetically "higher" than t                       *
  683.  *        <0 if t is alphabetically "higher" than s                       *
  684.  **************************************************************************/
  685. short compstra( char *s, char *t )
  686. {
  687.     for( ; tolower(*s) == tolower(*t); s++, t++)
  688.         if( !*s ) return 0;
  689.  
  690.     return (short)( tolower(*s)-tolower(*t) );
  691. }
  692.  
  693.  
  694. /**************************************************************************
  695.  * Print the prompt string passed as "a" and return the user's            *
  696.  * YES or NO equivalent result.  1=YES, 2=NO                              *
  697.  **************************************************************************/
  698. UBYTE PutQ( char *a )
  699. {
  700.     PutText( a );
  701.     return (UBYTE)(z->MCIcreg[0][0]=='1') ;
  702. }
  703.  
  704.  
  705. /**************************************************************************
  706.  * Isn't it obvious enough? ;-)
  707.  **************************************************************************/
  708. void DoReturn( void )
  709. {
  710.     PutText("\n");
  711. }
  712.  
  713.  
  714. /**************************************************************************
  715.  * Create the editor filename used for the current port and place it      *
  716.  * in the string array passed as "path"                                   *
  717.  **************************************************************************/
  718. void MakeEd( char *path )
  719. {
  720.     sprintf( path, "%s_edbuff%d", myp->gc.ZIPpath, z->InPort );
  721. }
  722.  
  723.  
  724. /**************************************************************************
  725.  * Delete the editor file                                                 *
  726.  **************************************************************************/
  727. void DeleteEd( void )
  728. {
  729.     char    filename[80];
  730.  
  731.     MakeEd    ( filename ) ;
  732.     DeleteFile( filename ) ;
  733. }
  734.  
  735. /**************************************************************************
  736.  * Open the file used for the editor and return the filehandle (BPTR)     *
  737.  **************************************************************************/
  738. BPTR OpenEd( long mode )
  739. {
  740.     char    filename[80];
  741.  
  742.     MakeEd( filename );
  743.  
  744.     return Open( filename, mode );
  745. }
  746.  
  747. /**************************************************************************
  748.  * insert the contents of the file belonging to filehandle "fp" into      *
  749.  * the current port's editor file                                         *
  750.  **************************************************************************/
  751. void PrepEditor( BPTR fp )
  752. {
  753.     BPTR    kp;
  754.     char    buff[100];
  755.  
  756.     if( fp ) {
  757.         if( kp = OpenEd( MODE_NEWFILE ) ) {
  758.             while( FGets( fp, buff, 82 ) && buff[0]!=26 )
  759.                    FPuts( kp, buff     ) ;
  760.  
  761.             Close( kp );
  762.         }
  763.     }
  764.     else    DeleteEd();
  765. }
  766.  
  767. /**************************************************************************
  768.  * Save the contents of the current port's editor file into the file      *
  769.  * belonging to filehandle "fp"                                           *
  770.  **************************************************************************/
  771. void SaveEditor( BPTR fp, UBYTE eof )
  772. {
  773.     BPTR    kp;
  774.     char    buff[100];
  775.  
  776.     if( kp = OpenEd( MODE_OLDFILE ) ) {
  777.         while( FGets( kp, buff, 82 ) && buff[0]!=26 )
  778.                FPuts( fp, buff     ) ;
  779.  
  780.         Close( kp );
  781.  
  782.         DeleteEd();
  783.     }
  784.  
  785.     if( eof ) FPuts( fp, "\032\n" );
  786. }
  787.  
  788.  
  789.